home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
asmutil
/
asm_n_z.zip
/
TK.ASM
< prev
next >
Wrap
Assembly Source File
|
1987-05-05
|
21KB
|
614 lines
page 55,132
title TK - Token Parsing filter
;
; TK --- A Simple Token Parsing Filter for DOS 2.0
;
; (c) Copyright 1984 by Jim Mott
; 3710 Slopeview Drive
; Sunnyvale, CA 95148
; (408) 274-2620
; All rights reserved. Permission granted to use this software for
; personal, noncommercial purposes only.
;
;
; This program is designed to be a filter for DOS 2.0.
; It will tokenize its input and allow subsetting and/or
; single token per line output.
;
; The format of the command is:
;
; TK {/RJx | /LJx} {/0} {{/v} | {/v/v}}
; where /RJx means right justify all tokens to x positions
; /LJx means left justify all tokens to x positions
; In the two entries x must be in [1..15]
; /0 means output one token per line
; /v means select token v for output. You may select any
; number, up to 255, of tokens to output. Repeats are
; allowed and you may change the order of the input tokens
; on the output line.
;
; For example, to extract the list of users from a VM directory file and
; write a sorted list of them without passwords to the printer the
; following command line would be used.
;
; FIND "USER " < DIRECT.VM | TK/LJ8/2/4/5/6/7/8/9 | SORT > PRN
;
;
; For example, to find a list of all sub-directories of the current
; directory sorted by sub-directory name we would use the following
; command line:
;
; DIR | FIND "<DIR>" | TK/LJ8/1/3/4 | SORT | MORE
;
;
; For example, to generate a sorted list of all words used in a document
; with one word per line we could use the following command line:
;
; TK/RJ8/0 < FOOBAR.DOC | SORT | MORE
;
;
;
;
;
;
;
;
;
;
;
;
stack segment para stack 'STACK'
db 8 dup('Jim Mott (408) 274-2620')
stack ends
;
;
dsect segment para 'DATA'
buffer db 255 dup('?') ; where to put the data
db ' ' ; be sure to end scan correctly
;
glen dw 0 ; length of gbuff
gbptr dw gbuff ; point to start of buffer
gbuff db 255 dup('G') ; buffer used by bufget
;
flag1 db ? ; options enabled
f1rj equ 01h ; right justify tokens
f1lj equ 02h ; left justify tokens
f1one equ 04h ; output one token per line
f1sub equ 08h ; substring function requested
f1work equ 10h ; fill trailing spaces
f1oerr equ 20h ; error in options string
f1eof equ 40h ; end of file on standard input device
f1qeof equ 80h ; queue the end of file
;
spaces db ? ; number of trailing spaces required
;
toksiz db ? ; token size if (f1rj or f1lj)
;
three db 3 ; length of each entry
tokcnt db ? ; count of tokens in table
toktbl db 3*255 dup('0') ; table of token pointers and lengths
;
outcnt db ? ; number of subsetting entries in
; outers
outers db 255 dup('1') ; list of token numbers to output
;
tokptr dw ? ; pointer to free token space
tokens db 900 dup('2') ; string space of tokens
;
msgver db 'TK: Incorrect DOS version. Must be at least 2.00.'
db 0dh,0ah,'$'
optmsg db 'TK: Incorrect parameters given.'
db 0dh,0ah
optmgl equ $ - optmsg
noroom db 'TK: No room for user on device.'
db 0dh,0ah
lnoroom equ $ - noroom
chrspa db ' ' ; a space to output
chrclf db 0dh,0ah ; <cr><lf> sequence
dsect ends
;
;
csect segment para 'CODE'
assume cs:csect,ds:dsect,ss:stack
;
main proc far
;
push ds ; set up a return address
sub ax,ax ; we want to return to DS:0000
push ax
mov ax,dsect ; point to start of data area
mov ds,ax ; make assume and reality agree
mov ah,30h ; get DOS version number
int 21h ; call OS to get it
cmp al,2 ; is it at least 2.00?
jnl main00 ; yesy - good enough
lea dx,msgver ; no - point to the "Bad DOS version"
mov ah,9 ; message and use DOS 1.?? function
int 21h ; call to print it.
ret ; and do a long return
;
main00: call options ; parse the options (at ES:80) and set
; flags
mov ax,ds ; make ES and DS the same now
mov es,ax ; so the string moves work nicely.
test flag1,f1oerr ; was there and error in the options
jz main01 ; no - then go with this baby
lea dx,optmsg ; yes - point to options error message
mov cx,optmgl ; get length of message
mov bx,2 ; error output device handle
mov ah,40h ; set DOS function number for
int 21h ; "write to file or device" & call DOS
jmp short main03 ; and return as done
;
main01: mov tokcnt,0 ; no tokens in the table
lea ax,tokens ; point to start of token work area
mov tokptr,ax ; save pointer to next free byte
call bufget ; read in a buffer
test flag1,f1eof ; is there any data in the read buffer
jnz main03 ; no - we are done with this pgm then
dec cx ; yes - ignore the trailing <cr>
jle main01 ; if length is =<0 just get next line
lea bx,buffer ; point to the first byte of the data
;
main02: call nextok ; get the next token
or cx,cx ; are we done with this line yet
jnz main02 ; no - get yet another token
call write ; write the lines
jmp short main01 ; and loop for the next line
;
main03: call crlf ; write a final <cr><lf> sequence
mov al,0 ; put 0 in al - return code to post
mov ah,4ch ; terminate a process code
int 21h ; end this program
;
main endp
;
;
; OPTIONS - This subroutine will parse the options passed to the
; program and set the required bits in flag1. No registers
; are preserved since we are called only once, before the
; program has really started.
;
options proc near
;
mov outcnt,0 ; initialize outers count
mov si,81h ; point to the first parms character
;
opt01: mov al,byte ptr es:0[si] ; get a byte from the parm string
inc si ; point to the next byte
cmp al,0dh ; is it the end of the string?
jne opt02 ; no - goody, more data to process
ret ; yes, return to the caller then
;
opt02: cmp al,' ' ; allow spaces anywhere before slashes
je opt01 ; ignore them though
cmp al,'/' ; we have to start with a slash now
je opt04 ; if it is a slash then process it
;
opterr: or flag1,f1oerr ; otherwise set the options error flag
ret ; and return
;
opt04: mov al,byte ptr es:0[si] ; get the next character after slash
inc si ; point to next character in parms
cmp al,'a' ; is it lower case or funny?
jl opt4a ; no - process it normally then
sub al,'a'-'A' ; yes - map lower case to upper
;
opt4a: cmp al,'L' ; might it be left justify or numeric
jl optnum ; perhaps numeric - check it out
jne opt05 ; it is not LJ for sure
or flag1,f1lj ; assume it is LJ for the moment
test flag1,f1rj ; make sure this isn't a duplicate
jnz opterr ; if RJ already then big problems
jmp short opt06 ; and rejoin common justify code
;
opt05: cmp al,'R' ; might it be right justify (RJ)?
jne opterr ; no - then it is an error
or flag1,f1rj ; yes - assume for the moment it is
test flag1,f1lj ; make sure we aren't trying to left
jnz opterr ; justify too - if we are we are in
; deep s..t
opt06: mov al,byte ptr es:0[si] ; get the next character
inc si ; point to the next character in parms
cmp al,'J' ; is it the J we expect?
je opt6a ; yes - process it normally then
cmp al,'j' ; is it a lower case J
jne opterr ; no - that's too bad.
;
opt6a: mov al,byte ptr es:0[si] ; get the first byte of the number
inc si ; point to next character in parms
call decbin ; is it a number?
jc opterr ; no - then we have an error
or al,al ; is the field size 0?
je opterr ; yes - it is in error then
cmp al,15 ; is field size more than 15?
jg opterr ; yes - it is in error then
mov toksiz,al ; save the justified field size
jmp short opt01 ; and process further options
;
optnum: call decbin ; is it a number after slash?
jc opterr ; no - then it is an error
or al,al ; zero is special
jne opt08 ; not zero - save it in array then
or flag1,f1one ; zero means one token per line
jmp short opt01 ; process some other token then
;
opt08: sub cx,cx ; get a zeroed double register
mov cl,outcnt ; get offset into outers for this guy
lea bx,outers ; point just before list of outers
add bx,cx ; bx points to origin 1 save spot